
/*--------------------------------------------------------------------------
移動後に攻撃範囲表示


■概要
　操作しているユニットを移動させた後、所持している武器で攻撃可能な範囲を表示します。
　通常は装備している武器の攻撃範囲を表示しますが、設定を触る事で所持している武器の最大攻撃範囲を表示する事も可能です。）

■カスタマイズ
　・所持している武器の最大攻撃範囲を表示したい
　　設定の中にある、
　　var isAllWeaponMaxRange = false;をvar isAllWeaponMaxRange = true;に書き換えてください


■注意点
　所持武器の射程を広げるようなスキルは現在、スキル_[強弓][近接射撃]のみ対応しています。
　対応が必要な場合は自分で修正するか、2chで要望を挙げてください。

修正内容
15/ 9/13　新規作成
15/ 9/13　移動せずその場で攻撃しようとすると範囲表示が変化しないバグを修正
　　　　　また、装備している武器の攻撃範囲を表示するよう修正
　　　　　（全所持武器の射程で表示すると、複数射程の武器を所持してる時に、装備武器が攻撃可能なのか判りづらかったので）
15/ 9/13　再移動可能なユニットで再移動が出来なくなるバグを修正
15/10/18　他のスクリプトと競合していると思われるMapLayer.prepareMapLayer()の実装を外し、UnitRangePanelクラスのみ修正する形に実装を直した
15/10/19　PlayerTurn.moveTurnCycle()をalias化
15/11/06　オートターンエンドON時、オートターンエンドが実施された次のターンに移動範囲表示が移動後のものになってしまうバグを修正
15/12/07　場所コマンドなど、移動後に発生したイベントでユニットを移動させた場合に攻撃範囲を消すスクリプトコマンドを追加
　　　　　メモリを頻繁に確保してしまう処理を修正
16/04/03　移動後に攻撃範囲表示と移動後に攻撃範囲表示(最大射程)を一本化
　　　　　一部処理を見直し、不要関数を削除
16/05/08　1.074対応
16/05/12　1.077対応
16/05/23　待機型移動範囲と自軍攻撃範囲の表示変更スクリプトとの併用に対応
19/04/21　スキル_[強弓][近接射撃]に対応
22/03/21　移動後のユニットコマンドなどでユニットが消去になった時、移動範囲のパネルが残るバグを修正


■対応バージョン
　SRPG Studio Version:1.254


■規約
・利用はSRPG Studioを使ったゲームに限ります。
・商用・非商用問いません。フリーです。
・加工等、問題ありません。どんどん改造してください。
・クレジット明記無し　OK
・再配布、転載　OK
・wiki掲載　OK
・SRPG Studio利用規約は遵守してください。

--------------------------------------------------------------------------*/
(function() {


//-------------------------------------------
// 設定
//-------------------------------------------
// 移動後、所持している武器の最大攻撃範囲を表示するか（true:表示する、false:装備している武器の攻撃範囲を表示）
var isAllWeaponMaxRange = false;

var SKILL_WORD_PROXIMITY_FIRE = 'Proximity_fire';
var SKILL_WORD_SUPERBOW       = 'superbow';




//-------------------------------------------
// 以下、プログラム用のデータ
//-------------------------------------------
var MoveEndFlag = {
	MOVE_OK: 0,
	MOVE_END: 1,
	MOVE_REPEAT: 2,		// 再移動時の表示処理（１回目）
	MOVE_REPEAT2: 3		// 再移動時の表示処理（２回目以降）
};



//-------------------------------------------
// PlayerTurnクラス
//-------------------------------------------

var alias1 = PlayerTurn.moveTurnCycle;
PlayerTurn.moveTurnCycle= function() {
		var mode = this.getCycleMode();
		var result = alias1.call(this);
		
		// ユニットコマンド表示中及びユニットエリア表示中以外は、通常の移動＆武器範囲表示を行うようフラグを設定
		if (mode !== PlayerTurnMode.UNITCOMMAND && mode !== PlayerTurnMode.AREA) {
			if( this._mapSequenceArea._unitRangePanel != null ){
				this._mapSequenceArea._unitRangePanel.setMoveEndFlag(MoveEndFlag.MOVE_OK);
			}
		}
		
		return result;
};


var alias2 = PlayerTurn._prepareTurnMemberData;
PlayerTurn._prepareTurnMemberData= function() {
		alias2.call(this);
		// ターン開始時にマップレイヤの移動完了フラグをクリア
		var unit_range_panel = MapLayer.getUnitRangePanel();
		unit_range_panel.setMoveEndFlag(MoveEndFlag.MOVE_OK);

};


PlayerTurn._moveArea= function() {
		var result = this._mapSequenceArea.moveSequence();
		
		if (result === MapSequenceAreaResult.COMPLETE) {
//			this._mapEdit.clearRange();		// 対象ユニットを消さない（消えると移動範囲や攻撃範囲の表示が出来ない）

			this._mapSequenceArea._unitRangePanel.setMoveEndFlag(MoveEndFlag.MOVE_END);

			this._mapSequenceCommand.openSequence(this);
			this.changeCycleMode(PlayerTurnMode.UNITCOMMAND);
		}
		else if (result === MapSequenceAreaResult.CANCEL) {
			// キャンセルされたら、移動完了フラグをクリア
			this._mapSequenceArea._unitRangePanel.setMoveEndFlag(MoveEndFlag.MOVE_OK);

			this.changeCycleMode(PlayerTurnMode.MAP);
		}
		else if (result === MapSequenceAreaResult.NONE) {
			// 移動完了でもキャンセルでもない場合も、移動完了フラグをクリア
			this._mapSequenceArea._unitRangePanel.setMoveEndFlag(MoveEndFlag.MOVE_OK);
		}
		
		return MoveResult.CONTINUE;
};




//-------------------------------------------
// MapSequenceCommandクラス
//-------------------------------------------
MapSequenceCommand._doLastAction= function() {
		var i;
		var unit = null;
		var list = PlayerList.getSortieList();
		var count = list.getCount();
		
		// コマンドの実行によってユニットが存在しなくなる可能性も考えられるため確認
		for (i = 0; i < count; i++) {
			if (this._targetUnit === list.getData(i)) {
				unit = this._targetUnit;
				break;
			}
		}
		
		// ユニットが依然として存在するかどうか
		if (unit !== null) {
			if (this._unitCommandManager.getExitCommand() !== null) {
				if (!this._unitCommandManager.isRepeatMovable()) {
					// 再移動が許可されていない場合は、再移動が発生しないようにする
					this._targetUnit.setMostResentMov(ParamBonus.getMov(this._targetUnit));
				}
				else{
					this._parentTurnObject._mapSequenceArea._unitRangePanel.setMoveEndFlag(MoveEndFlag.MOVE_REPEAT);
				}
				
				// ユニットは何らかの行動をしたため、待機状態にする
				this._parentTurnObject.recordPlayerAction(true);
				
				MapLayer.getMarkingPanel().updateMarkingPanel();
				
				return 0;
			}
			else {
				// ユニットは行動しなかったため、位置とカーソルを戻す
				this._parentTurnObject.setPosValue(unit);
			}
			
			// 向きを正面にする
			unit.setDirection(DirectionType.NULL);
		}
		else {
			this._parentTurnObject.recordPlayerAction(true);
			// ユニットが消えた場合は明示的に移動範囲のパネルを消す
			this._parentTurnObject.clearPanelRange();
			
			return 1;
		}
		
		return 2;
};




//-------------------------------------------
// UnitRangePanelクラス
//-------------------------------------------
// 初期化
var alias3 = UnitRangePanel.initialize;
UnitRangePanel.initialize= function() {
		alias3.call(this);

		this._ismoveend  = 0;	// 追加変数初期化(移動終了状態)
		this._repeat_mov = 0;	// 追加変数初期化(再移動歩数)
		this._prev_ismoveend  = 0;	// 追加変数初期化
};


// 移動範囲や攻撃範囲の表示
UnitRangePanel.drawRangePanel= function() {
		// 対象ユニットがなければ表示しない
		if (this._unit === null) {
			return;
		}
		
//		if (PosChecker.getUnitFromPos(this._x, this._y) !== this._unit) {
//			return;
//		}

		// 対象ユニットが既に行動完了なら表示しない
		if (this._unit.isWait()) {
			return;
		}

		// _ismoveendがMoveEndFlag.MOVE_ENDなら移動完了しているので、武器の攻撃範囲表示に切り替え
		if( this._ismoveend === MoveEndFlag.MOVE_END ){
			if( this._prev_ismoveend != this._ismoveend ) {
				this._setRangeData2();
				this._prev_ismoveend = this._ismoveend;
			}
		}
		// _ismoveendがMoveEndFlag.MOVE_OKなら移動前なので、通常の範囲表示に切り替え
		else if( this._ismoveend === MoveEndFlag.MOVE_OK ){
			if( this._prev_ismoveend != this._ismoveend ) {
				this._setRangeData();
				this._prev_ismoveend = this._ismoveend;
			}
		}
		// _ismoveendがMoveEndFlag.MOVE_REPEATなら再移動なので、再移動用の表示に切り替え
		else if( this._ismoveend === MoveEndFlag.MOVE_REPEAT ){
			if( this._prev_ismoveend != this._ismoveend ) {
				this._setRepeatRangeData();
				this._prev_ismoveend = this._ismoveend;
			}
			this._ismoveend = MoveEndFlag.MOVE_REPEAT2;		// 再移動2に切替
		}
		// _ismoveendがMoveEndFlag.MOVE_REPEAT2なら再移動2なので、再移動2用の表示に切り替え
		else if( this._ismoveend === MoveEndFlag.MOVE_REPEAT2 ){
			if( this._prev_ismoveend != this._ismoveend ) {
				this._setRepeatRangeData();
				this._prev_ismoveend = this._ismoveend;
			}
		}
		
		// 移動範囲と攻撃範囲の表示
		this._mapChipLight.drawLight();
		this._mapChipLightWeapon.drawLight();

		// 杖範囲の表示(待機型移動範囲と自軍攻撃範囲の表示変更スクリプトとの併用箇所)
		if( typeof WAND_RANGE_DISPLAY !== 'undefined' && WAND_RANGE_DISPLAY == true ) {
			this._mapChipLightWand.drawLight();
		}
};


// 移動完了フラグの設定用メソッド（上位から呼び出す）
UnitRangePanel.setMoveEndFlag= function(value) {
		this._ismoveend = value;
};


// 移動範囲と攻撃範囲の設定（移動完了後の武器範囲表示用）
UnitRangePanel._setRangeData2= function() {
		var i, item, count, rangeMetrics;
		var startRange = 99;
		var endRange = 0;
		var isWeapon = 0;
		var mov = 0;			// 移動完了後の武器範囲表示なので、移動力は0にしている
		
		// 装備している武器の攻撃範囲を表示する場合
		if( isAllWeaponMaxRange != true ) {
			// 自軍の場合は、装備武器を参照する
			item = ItemControl.getEquippedWeapon(this._unit);
			rangeMetrics = this._getRangeMetricsFromItem2(this._unit, item);
			if (rangeMetrics !== null) {
				startRange = rangeMetrics.startRange;
				endRange = rangeMetrics.endRange;
				isWeapon = 1;
			}
		}
		// 所持している武器の最大攻撃範囲を表示する場合
		else {
			// 最も射程がある武器を参照する
			count = UnitItemControl.getPossessionItemCount(this._unit);
			for (i = 0; i < count; i++) {
				item = UnitItemControl.getItem(this._unit, i);
				rangeMetrics = this._getRangeMetricsFromItem2(this._unit, item);
				if (rangeMetrics !== null) {
					if (rangeMetrics.startRange < startRange) {
						startRange = rangeMetrics.startRange;
					}
					if (rangeMetrics.endRange > endRange) {
						endRange = rangeMetrics.endRange;
					}
					
					if( endRange !== 0 ) {
						isWeapon = 1;
					}
				}
			}
		}
		
		if (isWeapon) {
			this._simulator.startSimulationWeapon(this._unit, mov, startRange, endRange);
		}
		else {
			this._simulator.startSimulation(this._unit, mov);
		}
		
		// 杖範囲の表示(待機型移動範囲と自軍攻撃範囲の表示変更スクリプトとの併用箇所)
		if( typeof WAND_RANGE_DISPLAY !== 'undefined' && WAND_RANGE_DISPLAY == true ) {
			// 杖の範囲を表示する場合、杖の射程を参照する
			count = UnitItemControl.getPossessionItemCount(this._unit);
			i = 0;
			while ( i < count ) {
				item = UnitItemControl.getItem(this._unit, i);
				rangeMetrics = this._getRangeMetricsFromWand(this._unit, item);
				if (rangeMetrics !== null) {
					if (rangeMetrics.startRange < startRange) {
						startRange = rangeMetrics.startRange;
					}
					if (rangeMetrics.endRange > endRange) {
						endRange = rangeMetrics.endRange;
					}
					
					if( endRange !== 0 ) {
						isWeapon |= 2;
					}
				}
				i++;
			}
			
			if (isWeapon & 2) {
				this._simulator_wand.startSimulationWeapon(this._unit, mov, startRange, endRange);
			}
		}
		// 杖範囲の表示(待機型移動範囲と自軍攻撃範囲の表示変更スクリプトとの併用箇所ここまで)
		
		this._setLight(isWeapon);
};


// ユニットの攻撃範囲取得
UnitRangePanel._getRangeMetricsFromItem2= function(unit, item) {
		var rangeMetrics = null;
		
		if (item == null ) {
			return rangeMetrics;
		}
		
		if (item.isWeapon()) {
			if (ItemControl.isWeaponAvailable(unit, item)) {
				rangeMetrics = StructureBuilder.buildRangeMetrics();
				rangeMetrics.startRange = this._getStartRangeFromItemAndSkill2(unit, item);
				rangeMetrics.endRange = this._getEndRangeFromItemAndSkill2(unit, item);
			}
		}
		
		return rangeMetrics;
}


// 武器の攻撃開始範囲取得
UnitRangePanel._getStartRangeFromItemAndSkill2= function(unit, item) {
		var skill;
		var startRange = item.getStartRange();
		
		// 近接射撃スキルへの対応処理
		skill = SkillControl.getPossessionCustomSkill(unit, SKILL_WORD_PROXIMITY_FIRE );
		if(skill){
			if(item.custom.wtype == 3){
				startRange = 1;
			}
		}
		
		return startRange;
}


// 武器の攻撃終了範囲取得
UnitRangePanel._getEndRangeFromItemAndSkill2= function(unit, item) {
		var skill;
		var endRange = item.getEndRange();
		
		// 強弓スキルへの対応処理
		skill = SkillControl.getPossessionCustomSkill(unit, SKILL_WORD_SUPERBOW );
		if(skill){
			if(item.custom.wtype == 3){
				endRange += 1;
			}
		}
		
		return endRange;
}


})();